From 8d547cb2524e3644ec9a5cf2a664b2924cca2d7a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Dec 2005 16:14:20 +0100 Subject: [PATCH] Simplify console driver and avoid unnecessary spinning in the transmit handler. Signed-off-by: Keir Fraser --- .../arch/xen/i386/mm/pgtable.c | 1 - .../drivers/xen/console/console.c | 56 ++++++++----------- .../drivers/xen/console/xencons_ring.c | 15 ++--- .../drivers/xen/console/xencons_ring.h | 23 -------- .../include/asm-xen/xencons.h | 7 +++ 5 files changed, 33 insertions(+), 69 deletions(-) delete mode 100644 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c index 6431722c25..c904a1fd44 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c @@ -389,7 +389,6 @@ void pgd_free(pgd_t *pgd) } #ifndef CONFIG_XEN_SHADOW_MODE -asmlinkage int xprintk(const char *fmt, ...); void make_lowmem_page_readonly(void *va) { pte_t *pte = virt_to_ptep(va); diff --git a/linux-2.6-xen-sparse/drivers/xen/console/console.c b/linux-2.6-xen-sparse/drivers/xen/console/console.c index 137af277f3..22f18b1511 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c @@ -55,7 +55,6 @@ #include #include -#include "xencons_ring.h" /* * Modes: * 'xencons=off' [XC_OFF]: Console is disabled. @@ -247,7 +246,6 @@ void xencons_force_flush(void) if (xen_start_info->flags & SIF_INITDOMAIN) return; - /* Spin until console data is flushed through to the daemon. */ while (wc != wp) { int sent = 0; @@ -271,8 +269,7 @@ static struct tty_struct *xencons_tty; static int xencons_priv_irq; static char x_char; -/* Non-privileged receive callback. */ -static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { int i; unsigned long flags; @@ -311,10 +308,9 @@ static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) spin_unlock_irqrestore(&xencons_lock, flags); } -/* Privileged and non-privileged transmit worker. */ static void __xencons_tx_flush(void) { - int sz, work_done = 0; + int sent, sz, work_done = 0; if (xen_start_info->flags & SIF_INITDOMAIN) { if (x_char) { @@ -340,20 +336,18 @@ static void __xencons_tx_flush(void) } while (wc != wp) { - int sent; sz = wp - wc; if (sz > (wbuf_size - WBUF_MASK(wc))) sz = wbuf_size - WBUF_MASK(wc); sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); - if (sent > 0) { - wc += sent; - work_done = 1; - } + if (sent == 0) + break; + wc += sent; + work_done = 1; } } - if (work_done && (xencons_tty != NULL)) - { + if (work_done && (xencons_tty != NULL)) { wake_up_interruptible(&xencons_tty->write_wait); if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && (xencons_tty->ldisc.write_wakeup != NULL)) @@ -361,31 +355,26 @@ static void __xencons_tx_flush(void) } } -/* Privileged receive callback and transmit kicker. */ -static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +void xencons_tx(void) { - static char rbuf[16]; - int i, l; unsigned long flags; spin_lock_irqsave(&xencons_lock, flags); + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); +} - if (xencons_tty != NULL) - { - /* Receive work. */ - while ((l = HYPERVISOR_console_io( - CONSOLEIO_read, 16, rbuf)) > 0) - for (i = 0; i < l; i++) - tty_insert_flip_char(xencons_tty, rbuf[i], 0); - if (xencons_tty->flip.count != 0) - tty_flip_buffer_push(xencons_tty); - } +/* Privileged receive callback and transmit kicker. */ +static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + static char rbuf[16]; + int l; - /* Transmit work. */ - __xencons_tx_flush(); + while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0) + xencons_rx(rbuf, l, regs); - spin_unlock_irqrestore(&xencons_lock, flags); + xencons_tx(); return IRQ_HANDLED; } @@ -664,7 +653,8 @@ static int __init xencons_init(void) if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) { printk("WARNING: Failed to register Xen virtual " "console driver as '%s%d'\n", - DRV(xencons_driver)->name, DRV(xencons_driver)->name_base); + DRV(xencons_driver)->name, + DRV(xencons_driver)->name_base); put_tty_driver(xencons_driver); xencons_driver = NULL; return rc; @@ -681,8 +671,6 @@ static int __init xencons_init(void) "console", NULL); BUG_ON(xencons_priv_irq < 0); - } else { - xencons_ring_register_receiver(xencons_rx); } printk("Xen virtual console successfully installed as %s%d\n", diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c index 2d6eb044b6..ea7bfe4e22 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c @@ -19,11 +19,9 @@ #include #include #include -#include "xencons_ring.h" #include static int xencons_irq; -static xencons_receiver_func *xencons_receiver; static inline struct xencons_interface *xencons_interface(void) { @@ -69,10 +67,8 @@ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) BUG_ON((prod - cons) > sizeof(intf->in)); while (cons != prod) { - if (xencons_receiver != NULL) - xencons_receiver( - intf->in + MASK_XENCONS_IDX(cons++, intf->in), - 1, regs); + xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs); + cons++; } mb(); @@ -80,12 +76,9 @@ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) notify_daemon(); - return IRQ_HANDLED; -} + xencons_tx(); -void xencons_ring_register_receiver(xencons_receiver_func *f) -{ - xencons_receiver = f; + return IRQ_HANDLED; } int xencons_ring_init(void) diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h deleted file mode 100644 index 25af2107f0..0000000000 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _XENCONS_RING_H -#define _XENCONS_RING_H - -asmlinkage int xprintk(const char *fmt, ...); - -int xencons_ring_init(void); -int xencons_ring_send(const char *data, unsigned len); - -typedef void (xencons_receiver_func)( - char *buf, unsigned len, struct pt_regs *regs); -void xencons_ring_register_receiver(xencons_receiver_func *f); - -#endif /* _XENCONS_RING_H */ - -/* - * Local variables: - * c-file-style: "linux" - * indent-tabs-mode: t - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ diff --git a/linux-2.6-xen-sparse/include/asm-xen/xencons.h b/linux-2.6-xen-sparse/include/asm-xen/xencons.h index 4b4909ba91..fa2160d89d 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/xencons.h +++ b/linux-2.6-xen-sparse/include/asm-xen/xencons.h @@ -4,4 +4,11 @@ void xencons_force_flush(void); void xencons_resume(void); +/* Interrupt work hooks. Receive data, or kick data out. */ +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs); +void xencons_tx(void); + +int xencons_ring_init(void); +int xencons_ring_send(const char *data, unsigned len); + #endif /* __ASM_XENCONS_H__ */ -- 2.30.2